/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package entidade.controller.JSF;

import entidade.controller.JPA.PermissaoJpaController;
import entidade.controller.JPA.TipoUsuarioJpaController;
import entidade.controller.JPA.UsuarioJpaController;
import entidade.controller.JPA.exceptions.IllegalOrphanException;
import entidade.controller.JPA.exceptions.RollbackFailureException;
import entidade.controller.JSF.util.PagingInfo;
import entidade.persistencia.Permissao;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.FacesException;
import entidade.controller.JSF.util.JsfUtil;
import entidade.controller.JPA.exceptions.NonexistentEntityException;
import entidade.persistencia.TipoUsuario;
import entidade.persistencia.Usuario;
import java.util.ArrayList;
import java.util.Date;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.model.SelectItem;

/**
 *
 * @author victorinox
 */
public class PermissaoController {

    private String loginEmail = "aaa";
    private String loginPwd = "aaa";
    private Integer usuarioLogadoId;

    public PermissaoController() {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        jpaController = (PermissaoJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "permissaoJpa");
        pagingInfo = new PagingInfo();
        pagingInfo.setBatchSize(20);
        converter = new PermissaoConverter();
    }
    private Permissao permissao = null;
    private List<Permissao> permissaoItems = null;
    private PermissaoJpaController jpaController = null;
    private PermissaoConverter converter = null;
    private PagingInfo pagingInfo = null;

    public PagingInfo getPagingInfo() {
        if (pagingInfo.getItemCount() == -1) {
            pagingInfo.setItemCount(jpaController.getPermissaoCount());
        }
        return pagingInfo;
    }

    public String initPage(Object obj) {

        return "";
    }

    public void normalizePermissions(String pageName) {

        try {
            FacesContext facesContext = FacesContext.getCurrentInstance();
            PermissaoJpaController permissaoJPAController = (PermissaoJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "permissaoJpa");
            TipoUsuarioJpaController tipoUsuarioJPAController = (TipoUsuarioJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "tipoUsuarioJpa");

            Permissao perm = permissaoJPAController.findPermissaoByName(pageName);
            if (perm == null) {
                perm = new Permissao(null, pageName);
                permissaoJPAController.create(perm);
            }

            TipoUsuario tipoUsuario = tipoUsuarioJPAController.findTipoUsuarioByName(TipoUsuarioController.TIPOUSUARIO_ADMIN_NOME);
            if (tipoUsuario == null) {
                tipoUsuario = new TipoUsuario(null, TipoUsuarioController.TIPOUSUARIO_ADMIN_NOME);
                tipoUsuarioJPAController.create(tipoUsuario);
            }
            tipoUsuario.setPermissaoCollection(permissaoJPAController.findPermissaoEntities());
            List<TipoUsuario> tipoUsuarioList = perm.getTipoUsuarioCollection();
            if (tipoUsuarioList == null) {
                tipoUsuarioList = new ArrayList<TipoUsuario>();
            }
            boolean find = false;
            for (int i = 0; i < tipoUsuarioList.size(); i++) {
                TipoUsuario tipousuatioTemp = tipoUsuarioList.get(i);
                if (tipousuatioTemp.getNome().equals(TipoUsuarioController.TIPOUSUARIO_ADMIN_NOME)) {
                    find = true;
                }
            }
            if (!find) {
                tipoUsuarioList.add(tipoUsuarioJPAController.findTipoUsuario(tipoUsuario.getTipoUsuarioId()));
                perm.setTipoUsuarioCollection(tipoUsuarioList);
                permissaoJPAController.edit(perm);
            }
            tipoUsuarioJPAController.edit(tipoUsuario);

        } catch (RollbackFailureException ex) {
            Logger.getLogger(PermissaoController.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            Logger.getLogger(PermissaoController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public Boolean usuarioLogadoPossuiPermissao(String pageName) {
        Usuario usr = getUsuarioLogado();
        if (usr != null) {
            List<Permissao> perms = usr.getTipoUsuarioId().getPermissaoCollection();
            for (int i = 0; i < perms.size(); i++) {
                Permissao perm = perms.get(i);
                if (perm.getPagina().equals(pageName)) {
                    return true;
                }
            }
        }
        return false;
    }

    public SelectItem[] getPermissaoItemsAvailableSelectMany() {
        return JsfUtil.getSelectItems(jpaController.findPermissaoEntities(), false);
    }

    public SelectItem[] getPermissaoItemsAvailableSelectOne() {
        return JsfUtil.getSelectItems(jpaController.findPermissaoEntities(), true);
    }

    public Permissao getPermissao() {
        if (permissao == null) {
            permissao = (Permissao) JsfUtil.getObjectFromRequestParameter("jsfcrud.currentPermissao", converter, null);
        }
        if (permissao == null) {
            permissao = new Permissao();
        }
        return permissao;
    }

    public String listSetup() {
        reset(true);
        return "permissao_list";
    }

    public String createSetup() {
        reset(false);
        permissao = new Permissao();
        return "permissao_create";
    }

    public String create() {
        try {
            jpaController.create(permissao);
            JsfUtil.addSuccessMessage("Permissao was successfully created.");
        } catch (Exception e) {
            JsfUtil.ensureAddErrorMessage(e, "A persistence error occurred.");
            return null;
        }
        return listSetup();
    }

    public String detailSetup() {
        return scalarSetup("permissao_detail");
    }

    public String editSetup() {
        return scalarSetup("permissao_edit");
    }

    private String scalarSetup(String destination) {
        reset(false);
        permissao = (Permissao) JsfUtil.getObjectFromRequestParameter("jsfcrud.currentPermissao", converter, null);
        if (permissao == null) {
            String requestPermissaoString = JsfUtil.getRequestParameter("jsfcrud.currentPermissao");
            JsfUtil.addErrorMessage("The permissao with id " + requestPermissaoString + " no longer exists.");
            return relatedOrListOutcome();
        }
        return destination;
    }

    public String edit() {
        String permissaoString = converter.getAsString(FacesContext.getCurrentInstance(), null, permissao);
        String currentPermissaoString = JsfUtil.getRequestParameter("jsfcrud.currentPermissao");
        if (permissaoString == null || permissaoString.length() == 0 || !permissaoString.equals(currentPermissaoString)) {
            String outcome = editSetup();
            if ("permissao_edit".equals(outcome)) {
                JsfUtil.addErrorMessage("Could not edit permissao. Try again.");
            }
            return outcome;
        }
        try {
            jpaController.edit(permissao);
            JsfUtil.addSuccessMessage("Permissao was successfully updated.");
        } catch (NonexistentEntityException ne) {
            JsfUtil.addErrorMessage(ne.getLocalizedMessage());
            return listSetup();
        } catch (Exception e) {
            JsfUtil.ensureAddErrorMessage(e, "A persistence error occurred.");
            return null;
        }
        return detailSetup();
    }

    public String destroy() {
        String idAsString = JsfUtil.getRequestParameter("jsfcrud.currentPermissao");
        Integer id = new Integer(idAsString);
        try {
            jpaController.destroy(id);
            JsfUtil.addSuccessMessage("Permissao was successfully deleted.");
        } catch (NonexistentEntityException ne) {
            JsfUtil.addErrorMessage(ne.getLocalizedMessage());
            return relatedOrListOutcome();
        } catch (Exception e) {
            JsfUtil.ensureAddErrorMessage(e, "A persistence error occurred.");
            return null;
        }
        return relatedOrListOutcome();
    }

    private String relatedOrListOutcome() {
        String relatedControllerOutcome = relatedControllerOutcome();
        if (relatedControllerOutcome != null) {
            return relatedControllerOutcome;
        }
        return listSetup();
    }

    public List<Permissao> getPermissaoItems() {
        if (permissaoItems == null) {
            getPagingInfo();
            permissaoItems = jpaController.findPermissaoEntities(pagingInfo.getBatchSize(), pagingInfo.getFirstItem());
        }
        return permissaoItems;
    }

    public String next() {
        reset(false);
        getPagingInfo().nextPage();
        return "permissao_list";
    }

    public String prev() {
        reset(false);
        getPagingInfo().previousPage();
        return "permissao_list";
    }

    private String relatedControllerOutcome() {
        String relatedControllerString = JsfUtil.getRequestParameter("jsfcrud.relatedController");
        String relatedControllerTypeString = JsfUtil.getRequestParameter("jsfcrud.relatedControllerType");
        if (relatedControllerString != null && relatedControllerTypeString != null) {
            FacesContext context = FacesContext.getCurrentInstance();
            Object relatedController = context.getApplication().getELResolver().getValue(context.getELContext(), null, relatedControllerString);
            try {
                Class<?> relatedControllerType = Class.forName(relatedControllerTypeString);
                Method detailSetupMethod = relatedControllerType.getMethod("detailSetup");
                return (String) detailSetupMethod.invoke(relatedController);
            } catch (ClassNotFoundException e) {
                throw new FacesException(e);
            } catch (NoSuchMethodException e) {
                throw new FacesException(e);
            } catch (IllegalAccessException e) {
                throw new FacesException(e);
            } catch (InvocationTargetException e) {
                throw new FacesException(e);
            }
        }
        return null;
    }

    private void reset(boolean resetFirstItem) {
        permissao = null;
        permissaoItems = null;
        pagingInfo.setItemCount(-1);
        if (resetFirstItem) {
            pagingInfo.setFirstItem(0);
        }
    }

    public void validateCreate(FacesContext facesContext, UIComponent component, Object value) {
        Permissao newPermissao = new Permissao();
        String newPermissaoString = converter.getAsString(FacesContext.getCurrentInstance(), null, newPermissao);
        String permissaoString = converter.getAsString(FacesContext.getCurrentInstance(), null, permissao);
        if (!newPermissaoString.equals(permissaoString)) {
            createSetup();
        }
    }

    public Converter getConverter() {
        return converter;
    }

    /**
     * @return the loginName
     */
    public String getLoginEmail() {
        return loginEmail;
    }

    /**
     * @param loginName the loginName to set
     */
    public void setLoginEmail(String loginName) {
        this.loginEmail = loginName;
    }

    /**
     * @return the loginPwd
     */
    public String getLoginPwd() {
        return loginPwd;
    }

    /**
     * @param loginPwd the loginPwd to set
     */
    public void setLoginPwd(String loginPwd) {
        this.loginPwd = loginPwd;
    }

    public String login() {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        UsuarioJpaController uc = (UsuarioJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "usuarioJpa");
        Usuario usr = uc.findUsuarioByEmailAndPwd(loginEmail, loginPwd);

        if (usr != null) {
            usuarioLogadoId = usr.getUsuarioId();
            usr.setDataUltimoLogin(new Date());
            try {
                uc.edit(usr);
            } catch (IllegalOrphanException ex) {
                Logger.getLogger(PermissaoController.class.getName()).log(Level.SEVERE, null, ex);
            } catch (NonexistentEntityException ex) {
                Logger.getLogger(PermissaoController.class.getName()).log(Level.SEVERE, null, ex);
            } catch (RollbackFailureException ex) {
                Logger.getLogger(PermissaoController.class.getName()).log(Level.SEVERE, null, ex);
            } catch (Exception ex) {
                Logger.getLogger(PermissaoController.class.getName()).log(Level.SEVERE, null, ex);
            }
            System.out.println("Login: "  + usr.getNome() + " - " + new Date().toLocaleString());
            return "welcome";
        } else {
            JsfUtil.addErrorMessage("Email ou senha não encontrados.");
            return "login";
        }
    }

    public String logout() {
        usuarioLogadoId = null;
        return "login";
    }

    public String esqueciMinhaSenha() {
        usuarioLogadoId = null;
        return "esqueciMinhaSenha";
    }

    public String esqueciMinhaSenhaAction() {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        UsuarioJpaController uc = (UsuarioJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "usuarioJpa");
        if (uc.emailExist(loginEmail)) {
            return "login";
        } else {
            JsfUtil.addErrorMessage("Email não encontrado no banco de dados.");
            return "esqueciMinhaSenha";
        }

    }

    /**
     * @return the usuarioLogado
     */
    public Usuario getUsuarioLogado() {
        if (usuarioLogadoId != null) {
            FacesContext facesContext = FacesContext.getCurrentInstance();
            UsuarioJpaController uc = (UsuarioJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "usuarioJpa");
            return uc.findUsuario(usuarioLogadoId);
        } else {
            return null;
        }
    }
}
